package com.vic.Builder;

import com.vic.Utils.StringUtils;
import com.vic.Utils.dateUtils;
import com.vic.bean.constant;
import com.vic.bean.fieldInfo;
import com.vic.bean.tableInfo;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: Vic Ly
 */
public class builderQuery {
    private static final Logger log = LoggerFactory.getLogger(builderQuery.class);
    public static void execute(tableInfo tableInfo){
        File folder = new File(constant.QUERY_PATH);
        if(!folder.exists()){
            folder.mkdirs();
        }
        String queryClassName = tableInfo.getBeanName()+constant.SUFFIX_BEAN_QUERY;
        File poFile = new File(folder,queryClassName + ".java");
        // 接下来对生成的文件写入内容
        OutputStream out = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try {
            out = new FileOutputStream(poFile);
            osw = new OutputStreamWriter(out, "utf8");
            bw = new BufferedWriter(osw);

            // bw.write("package com.vic.entity;");
            bw.write("package " + constant.QUERY_PACKAGE + ";");
            bw.newLine();
            bw.write("import "+constant.GLOBAL_QUERY_PACKAGE+".BaseQuery;");
            bw.newLine();
            if (tableInfo.getHaveDateTime() || tableInfo.getHaveDate()) {
                bw.write("import java.util.Date;");
                bw.newLine();
            }

            builderComment.addCommentByClass(bw, tableInfo.getComment() + "查询对象");
            bw.newLine();
            bw.write("public class " + queryClassName + " extends BaseQuery {");
            bw.newLine();
            // 属性
            List<fieldInfo> extendList = new ArrayList<fieldInfo>(); // fuzzy start end
            for (fieldInfo field : tableInfo.getFieldList()) {
                builderComment.addCommentByField(bw, field.getComment());
                // 属性生成
                bw.write("\t" + constant.ACCESS_PRIVATE + " " + field.getJavaType() + " " + field.getPropertyName() + ";");
                bw.newLine();
                // String类型的参数
                if(ArrayUtils.contains(constant.SQL_STRING,field.getSqlType())){
                    bw.write("\tprivate "+field.getJavaType()+" "+field.getPropertyName()+constant.SUFFIX_BEAN_QUERY_FUZZY + ";");
                    bw.newLine();
                }
                // 日期时间类型
                if(ArrayUtils.contains(constant.SQL_DATE_TIME,field.getSqlType()) || ArrayUtils.contains(constant.SQL_DATE,field.getSqlType())){
                    bw.write("\tprivate String "+field.getPropertyName()+constant.SUFFIX_BEAN_QUERY_TIME_START +";");
                    bw.newLine();

                    bw.write("\tprivate String "+field.getPropertyName()+constant.SUFFIX_BEAN_QUERY_TIME_END +";");
                    bw.newLine();
                }
            }
            // set/get方法
            buildGetAndSet(bw,tableInfo.getFieldList());
            buildGetAndSet(bw,tableInfo.getFieldExtendList());

            bw.write("}");
            bw.flush();
        }catch (Exception e){
            log.error("创建Query文件失败",e);
        }finally {
            if(bw != null){
                try {
                    bw.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(osw != null){
                try {
                    osw.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
    private static void buildGetAndSet(BufferedWriter bw,List<fieldInfo> fieldInfoList)throws Exception{
        for (fieldInfo field:fieldInfoList){
            // 通过观察set/get方法可以发现形如xxx set+属性名(首字母大写) + (){xxx}
            String tempField = StringUtils.upperCaseFirstLetter(field.getPropertyName());
            bw.newLine();
            bw.write("\tpublic void set"+tempField+"("+field.getJavaType()+" "+field.getPropertyName()+") {");
            bw.newLine();
            bw.write("\t\tthis."+field.getPropertyName()+" = "+field.getPropertyName()+";");
            bw.newLine();
            bw.write("\t}");
            bw.newLine();

            bw.write("\tpublic "+field.getJavaType()+" get"+tempField+"() {");
            bw.newLine();
            bw.write("\t\treturn "+field.getPropertyName()+";");
            bw.newLine();
            bw.write("\t}");
            bw.newLine();
        }
    }
}
